$(function() {
	declareConfirmBox('comfirmDialogHandler');
	declareAlertDialog('There are some errors on server! Your data have not been saved!','returnToEditMode','save-error-dialog');
	//declareAlertDialog
	declareAlertDialog('Your data is not correct!','returnToEditMode');
});

/**
 * Predefined object id
 */
var gridId = "s3list";
var jQGridId = "#"+gridId;
var pagerId = "#fxPager";
var updateLink = "updateFxFactors.do";
var loadLink = "loadFxFactors.do";
var saveAllButtonId = 'saveAllButton';

/**
 * Utility variable
 */
var listEditedRowID = new Array();
var activeGrid = true;
var oldDataList = new Array();
var inValidRowId = new Array();

/**
 * Create table for fx Factor
 * @param fxFactorModel
 * @param param
 */
function populateFXFactor(fxFactorModel) {
	var grid = jQuery(jQGridId);
		grid.jqGrid(
				{
					url : loadLink,
					datatype : "json",
					postData : {Year:2012, ProdArea:1, Priority: 1},
					height: '100%',
					colNames : fxFactorModel.colNames,
					colModel : fxFactorModel.colModel,
					mtype : "POST",
					pager : pagerId,
					viewrecords : true,
					rownumbers : true,
					gridview : true,
					autowidth: false,
					editurl:'clientArray',
					caption: 'FX Factors Values',
					ondblClickRow: function (rowId, iRow, iCol, e)
					{
						onRowDbClickHandler(rowId);
					},
					loadComplete: function()
					{
						onLoadCompleteHandler();
					}
					,
					beforeSelectRow: function (rowid, e) {
						var iCol = $.jgrid.getCellIndex(e.target);
						beforeSelectRowHandler(grid,iCol, rowid);
	                }
				});
		addButtonToPager();
	
}

/**
 * This function will execute when user double click on any row of the grid
 * If the row is not in edit mode and the grid is ready, change the row to edit mode
 * and enable Save all button at the pager of the grid
 * @param rowId
 */
function onRowDbClickHandler(rowId)
{
	// this row is not in edit mode
	if (activeGrid && $("tr#"+rowId).attr("editable") != "1" ) {
		//save current data
		var data= {id:rowId,data:getGridData(gridId,rowId)};
		oldDataList.push(data);
		// mark this row
		listEditedRowID.push(rowId);
		// change this row to edit mode
		jQuery("#"+gridId).jqGrid('editRow',rowId);
		//enable save button
		enableCustomButton(saveAllButtonId);
	}
}

/**
 * This function will be execute when the data of the list has been loaded and before the render of the grid
 * Restore the listEditedRowID
 * Disable Save all button at the pager of the grid
 */
function onLoadCompleteHandler()
{
	listEditedRowID = new Array();
	disableCustomButton(saveAllButtonId);
}

/**
 * This function will execute when user click on the row
 * If the clicked column is clear column, the data of selected row will be restored
 * Nothing happen in the other case
 */
function beforeSelectRowHandler(grid,iCol, rowid)
{
    var clearColumn = getColumnIndexByName(grid,'clear');
    if (iCol >= clearColumn && activeGrid) {
        if (iCol == clearColumn)
        	{
        		jQuery(jQGridId).jqGrid('restoreRow',rowid);
        		//check old data list
        		removeFromOdlDataList(rowid);
        		//check EditedRowIdlist
        		listEditedRowID = removeOutOfList(rowid,listEditedRowID);
        		//removeFromInvalidRow
        		inValidRowId = removeOutOfList(rowid,inValidRowId);
        		markValidRow(rowid);
        	}
    }
 // prevent row selection if one click on the button
    return false;
}

/**
 * This function will add button to the pager of the grid
 */
function addButtonToPager()
{
	jQuery(jQGridId).jqGrid('navGrid', pagerId, {
		edit : false,
		add : false,
		del : false,
		search : false,
		refresh : true
	});
	addCustomButton(saveAllButtonId,"Save All","ui-icon-disk",'openConfirmBox();');
	disableCustomButton(saveAllButtonId);
}

/**
 * Clear all condition of the grid
 */
function clearFXCondition() {
	var postData = $(jQGridId).jqGrid('getGridParam','postData');
    try {
    	delete postData['year'];
    	delete postData['prodarea'];
    	delete postData['priority'];
    } catch (e) { }
}

/**
 * Add conditions to grid
 */
function addFXCondition() {
	
	// default requirement to reload grid.
	var params = {datatype:'json', page:1, search : true};
	// set load parameters
	var selectedYear     = document.searchForm.selectedYear.value;
	var selectedPrio     = document.searchForm.selectedPriority.value;
	var selectedProdArea = document.searchForm.selectedProdArea.value;	
	params.postData = {Year:selectedYear, Priority: selectedPrio, ProdArea: selectedProdArea};	
	jQuery(jQGridId).jqGrid("clearGridData", true).setGridParam(params);
}

/**
 * Load grid data based on current conditions of the grid
 */
function searchByFilter() {
	clearFXCondition();
	addFXCondition();
	jQuery(jQGridId).trigger("reloadGrid");
}

/**
 * This function will send JSON data which represent grid data to url
 * @param url
 */
function sendData(url)
{
	if (listEditedRowID.length>0)
		{
			var sendData = parseData(gridId,listEditedRowID);
			showSavingMessage(gridId);
			disableCustomButton(saveAllButtonId);
			$.ajax({
		        type: "POST", 		
		        url: url, 		
		        data: {fxTable:sendData},
		        processdata: true, 	
		        dataType: 'json',
		        success: function (json) {
		        	hideSavingMessage(gridId);
		        	//reset oldDataList
		        	oldDataList = new Array();
		            //update status of editted row
		            for (var i=0;i<listEditedRowID.length;++i)
		            	{
		            		$(jQGridId).jqGrid('setRowData',listEditedRowID[i],{Status:1});
		            	}
		            //clean listEditedRowID
		            listEditedRowID = new Array();
		        },
		        error: function()
		        {
		        	hideSavingMessage();
		        	enableCustomButton(saveAllButtonId);
		        	$(".loading").css("display", "none");
		        	openAlert('save-error-dialog');
		        }
		    });
		}
}

/**
 * This is the utility function which changes all row which are in the @listEditedRowID to edit mode
 */
function returnToEditMode()
{
	//change row in listEditedRowID to edit mode
	for (var i=0;i<listEditedRowID.length;++i)
	{
		$(jQGridId).jqGrid('editRow',listEditedRowID[i]);
	}
}

/**
 * This is the utility function which remove row with @rowid out of @oldDataList
 */
function removeFromOdlDataList(rowid)
{
	for (var i=0; i< oldDataList.length; ++i)
	{
		var obj = oldDataList[i];
		if (obj.id === rowid)
			{
				$(jQGridId).jqGrid('setRowData',rowid,obj.data);
				oldDataList.splice(i, 1);
			}
	}
}

/**
 * The function will execute when user click OK button of confirm box
 */
function comfirmDialogHandler()
{
	var saveSuccess=0;
    for (var i = 0; i < listEditedRowID.length + 1; i++) {
    	if ($("tr#"+listEditedRowID[i]).attr("editable") === "1") {
    		//save to client
			$(jQGridId).jqGrid('saveRow', listEditedRowID[i], 
				    { 
						aftersavefunc: function (rowid, response) {saveSuccess +=1;}
				});
		}
    }
    if (saveSuccess == listEditedRowID.length)
    	{
    		if (validateData())
    			sendData(updateLink);
    		else
    			openAlert();
    	}
    else
    	{
    		returnToEditMode();
    	}
}

/**
 * Validate: 
 * 	+ If the length of Comment is valid
 *  + Value of fx factor is number
 */
function validateData()
{
	//reset inValidRowId list
	unMarkAsInvalid(inValidRowId);
	inValidRowId = new Array();
	var gridIds = $(jQGridId).jqGrid("getDataIDs");
	for (var i=0; i<gridIds.length;++i)
		{
			var data = getGridData(gridId,gridIds[i]);
			if ((data['FX Plan'].length>0 && !isNumber(data['FX Plan']))
					||(data['FX RW'].length>0 && !isNumber(data['FX RW']))
					||(data['FX RWH'].length>0 && !isNumber(data['FX RWH']))
					||(parseFloat(data['FX Plan'])<0)
					||(parseFloat(data['FX RW'])<0)
					||(parseFloat(data['FX RWH'])<0)
				)
				{
						inValidRowId.push(gridIds[i]);
				};
		}
	if (inValidRowId.length>0)
		{
			markAsInvalid(inValidRowId);
			return false;
		}
	return true;
}
